﻿using System.Collections.Generic;
using System.Linq;

namespace dPet.Application.Services.Implementation
{
	using AutoMapper;
	using dPet.Application.DataObjects;
	using dPet.Domain.Models;
	using dPet.Domain.Repositories;
	using dPet.Infrastructure.Logging;
	using Hangerd;
	using Hangerd.Repository;

	public class BasicDataService : ServiceBase, IBasicDataService
	{
		#region Repository

		private readonly IHospitalRepository _hospitalRepository;
		private readonly IStaffRoleRepository _staffRoleRepository;

		#endregion

		#region Constructors

		public BasicDataService(
			IRepositoryContext unitOfWork,
			IHospitalRepository hospitalRepository,
			IStaffRoleRepository staffRoleRepository)
			: base(unitOfWork)
		{
			_hospitalRepository = hospitalRepository;
			_staffRoleRepository = staffRoleRepository;
		}
		
		#endregion

		#region Hospital

		public MessagedResult<bool> AddHospital(HospitalDto hospitalDto, IOperator @operator)
		{
			return TryLoggedOperate(@operator, "基础数据管理", "添加医院", (ref Hospital hospital) =>
			{
				hospital = new Hospital(hospitalDto.Name);

				hospital.Address = hospitalDto.Address;
				hospital.PhoneNumber = hospitalDto.PhoneNumber;
				hospital.FaxNumber = hospitalDto.FaxNumber;

				_hospitalRepository.Add(hospital, true);
				
				UnitOfWork.Commit();

				return true;
			});
		}

		public MessagedResult<bool> UpdateHospital(string hospitalId, HospitalDto hospitalDto, IOperator @operator)
		{
			return TryLoggedOperate(@operator, "基础数据管理", "更新医院", (ref Hospital hospital) =>
			{
				hospital = _hospitalRepository.Get(hospitalId, true);

				if (hospital == null)
				{
					throw new HangerdException("医院信息不存在");
				}

				hospital.Name = hospitalDto.Name;
				hospital.Address = hospitalDto.Address;
				hospital.PhoneNumber = hospitalDto.PhoneNumber;
				hospital.FaxNumber = hospitalDto.FaxNumber;

				_hospitalRepository.Update(hospital, true);
				
				UnitOfWork.Commit();

				return true;
			});
		}

		public IEnumerable<HospitalDto> GetHospitals()
		{
			var hospitals = _hospitalRepository.GetAll(false)
				.OrderByDescending(h => h.CreateTime);

			return Mapper.Map<IEnumerable<Hospital>, IEnumerable<HospitalDto>>(hospitals);
		}

		public HospitalDto GetHospital(string id)
		{
			var hospital = _hospitalRepository.Get(id, false);

			return Mapper.Map<Hospital, HospitalDto>(hospital);
		}

		#endregion

		#region Staff Role

		public MessagedResult<bool> AddStaffRole(StaffRoleDto staffRoleDto, IOperator @operator)
		{
			return TryLoggedOperate(@operator, "基础数据管理", "添加角色", (ref StaffRole staffRole) =>
			{
				staffRole = new StaffRole(staffRoleDto.Name, (Privileges)staffRoleDto.Privileges);

				_staffRoleRepository.Add(staffRole, true);
				
				UnitOfWork.Commit();

				return true;
			});
		}

		public MessagedResult<bool> UpdateStaffRole(string staffRoleId, StaffRoleDto staffRoleDto, IOperator @operator)
		{
			return TryLoggedOperate(@operator, "基础数据管理", "更新角色", (ref StaffRole staffRole) =>
			{
				staffRole = _staffRoleRepository.Get(staffRoleId, true);

				if (staffRole == null)
				{
					throw new HangerdException("角色信息不存在");
				}

				staffRole.Name = staffRoleDto.Name;
				staffRole.Privileges = (Privileges)staffRoleDto.Privileges;

				_staffRoleRepository.Update(staffRole, true);
				
				UnitOfWork.Commit();

				return true;
			});
		}

		public IEnumerable<StaffRoleDto> GetStaffRoles()
		{
			var roles = _staffRoleRepository.GetAll(false);

			return Mapper.Map<IEnumerable<StaffRole>, IEnumerable<StaffRoleDto>>(roles);
		}

		public StaffRoleDto GetStaffRole(string id)
		{
			var staffRole = _staffRoleRepository.Get(id, false);

			return Mapper.Map<StaffRole, StaffRoleDto>(staffRole);
		}

		#endregion
	}
}
